/**
 * 副作用锁
 * @description
 * 当 A 和 B 的改动互相影响时，需要分别监听 A 和 B 的改动并同步更新对方。
 *
 * 为避免互相影响出现无限循环等副作用，可以在 A 的改动监听中开启副作用锁，B 的监听中如果处于副作用锁时则不触发 A 的更改
 */
export default class EffectLock {
  constructor(
    /** 自动解锁延时时间 ms */
    delay?: number
  ) {
    if (delay) {
      this.delay = delay
    }
  }

  /** 是否已加锁 */
  locked = false

  /** 自动解锁延时 */
  delay = 100

  /** 解锁超时 */
  timer?: ReturnType<typeof setTimeout>

  /** 加锁 */
  lock() {
    this.locked = true

    this.timer && clearTimeout(this.timer)

    // 延时自动解锁
    this.timer = setTimeout(() => this.unlock(), this.delay)
  }

  /** 解锁 */
  unlock() {
    this.locked = false
  }
}
